-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proc: initial (local) process manager implementation #7048
Conversation
def send_signal(self, name: str, signal: int): | ||
"""Send `signal` to the specified named process.""" | ||
raise NotImplementedError | ||
|
||
def kill(self, name: str): | ||
"""Kill the specified named process.""" | ||
raise NotImplementedError | ||
|
||
def terminate(self, name: str): | ||
"""Terminate the specified named process.""" | ||
raise NotImplementedError | ||
|
||
def remove(self, name: str, force: bool = False): | ||
"""Remove the specified named process from this manager. | ||
|
||
If the specified process is still running, it will be forcefully killed | ||
if `force` is True`, otherwise an exception will be raised. | ||
|
||
Raises: | ||
ProcessNotTerminatedError if the specified process is still | ||
running and was not forcefully killed. | ||
""" | ||
raise NotImplementedError | ||
|
||
def cleanup(self): | ||
"""Remove stale (terminated) processes from this manager.""" | ||
raise NotImplementedError |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@karajan1001 the next set of tasks will be to fill out these methods.
send_signal
,terminate
,kill
are all related and would be grouped together in the first task. Implementation/behavior for these methods should work the same as they do insubprocess
andmultiprocessing
(https://docs.python.org/3/library/subprocess.html#subprocess.Popen.send_signal).remove
andcleanup
can be implemented onceterminate
/kill
are done (since force-removing a child process directory will require killing the process if it is still running)
2f4b768
to
0754aed
Compare
proc.start() | ||
# Do not terminate the child daemon when the main process exits | ||
# pylint: disable=protected-access | ||
mp.process._children.discard(proc) # type: ignore[attr-defined] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is kind of a hack, but even if we subclassed multiprocessing.Process
we would just end up with an overridden
def start(self):
super().start()
_children.discard(self)
which I'm not sure is any cleaner
But in general, the idea behind using multiprocessing is that it allows us to use spawn
instead of fork
on windows + mac (#4294), and also allows us to directly run the target python function we want instead of adding the overhead from using dvc.daemon
+ a new dedicated CLI command
def __iter__(self): | ||
return self.processes() | ||
|
||
def __getitem__(self, key: str) -> "ProcessInfo": | ||
info_path = os.path.join(self.wdir, key, f"{key}.json") | ||
try: | ||
with open(info_path, encoding="utf-8") as fobj: | ||
return ProcessInfo.from_dict(json.load(fobj)) | ||
except FileNotFoundError: | ||
raise KeyError | ||
|
||
def get(self, key: str, default=None): | ||
try: | ||
return self[key] | ||
except KeyError: | ||
return default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also in the future we probably want this to just mirror the standard dict/Mapping interface (and in processes()
) so that we can return the paired name + info as needed instead of just the info from this initial implementation
0754aed
to
2107127
Compare
- supports running (backgrounded) processes with redirected output
2107127
to
d69d9df
Compare
β I have followed the Contributing to DVC checklist.
π If this PR requires documentation updates, I have created a separate PR (or issue, at least) in dvc.org and linked it here.
Thank you for the contribution - we'll try to review it as soon as possible. π
Related to #6267
Local prerequisite for #7002
dvc.proc
module for managing background processesmultiprocessing.Process(daemon=True)
Functionality is not used anywhere else in DVC yet (exp tempdir/queue runs will be the first place it gets added)
Python shell demo: